package com.zhenzhang.myblog.service;

import com.zhenzhang.myblog.dao.UserDao;
import com.zhenzhang.myblog.entity.role.User;
import com.zhenzhang.myblog.exception.JsonException;
import com.zhenzhang.myblog.exception.UsernameDuplicateException;
import com.zhenzhang.myblog.utils.AssetsManager;
import com.zhenzhang.myblog.utils.FileUtils;
import org.springframework.core.io.UrlResource;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.net.MalformedURLException;
import java.nio.file.Files;
import java.nio.file.Path;

@Service
public class UserService {
    @Resource
    private UserDao userDao;

    /**
     * 获取用户头像Resource资源
     * @param username 用户名
     * @return 头像文件在本地文件系统中的UrlResource对象。如果用户没有头像或用户名不存在则返回null
     */
    public UrlResource getUserAvatarResource(String username) {
        String avatar = userDao.getUserAvatar(username);
        if (username == null) {
            return null;
        }
        Path path = AssetsManager.getUserAvatarPath(avatar);
        if (!Files.exists(path) || Files.isDirectory(path)) {
            return null;
        }
        try {
            return new UrlResource(path.toUri());
        } catch (MalformedURLException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 向系统添加一个普通用户（会忽略掉user的管理员属性）
     * @param user 需要添加的用户信息
     * @throws UsernameDuplicateException 当数据库存在同名的用户名时抛出
     */
    public void addUser(User user) {
        try {
            user.setAdmin(false);
            userDao.addUser(user);
        } catch (DuplicateKeyException e) {
            throw new UsernameDuplicateException();
        }
    }

    /**
     * 验证密码是否与用户名匹配，若验证失败将抛出异常，若验证成功则返回数据库中的该用户信息
     * @param username 用户名
     * @param password 密码
     * @return 验证通过时，用于校验的数据库中获取的用户信息
     * @throws JsonException 用户不存在时抛出（代码404），密码验证不正确时抛出（代码401）
     */
    public User validUser(String username, String password) {
        var user = userDao.findUserByUsername(username);
        if (user == null) {
            throw new JsonException(404, "用户不存在");
        }
        if (!user.isPasswordEqual(password)) {
            throw new JsonException(401, "密码不正确");
        }
        return user;
    }

    /**
     * 设置头像,将图片文件重命名为ava_{用户名}.文件后缀,然后保存至项目运行目录
     * @param username 当前登录用户的用户名
     * @param file  前端表单传入的文件
     * @throws JsonException 文件大小超过3MB和上传不支持其格式的文件时抛出（代码400）
     */
    public void setAvatar(String username, MultipartFile file) {
        if(file.getSize() > 1024*1024*3) {
            throw new JsonException(400,"文件不得超过3MB");
        }
        String originFilename = file.getOriginalFilename();
        if (originFilename == null) {
            originFilename = "a.jpg";
        }
        String suffix = FileUtils.getSuffix(originFilename);
        if (!FileUtils.contain(suffix)) {
            throw new JsonException(400,"仅支持jpg,jpeg,gif,png格式文件");
        }
        try{
            String avatarFileName = username + "." + suffix;
            userDao.setAvatar(username, avatarFileName);
            Path savePath = AssetsManager.getUserAvatarPath(avatarFileName);
            file.transferTo(savePath);
        }catch (IOException e) {
            throw new JsonException(500,e.getMessage());
        }

    }

}
